home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / hoster / pvmwinrexec.c < prev    next >
C/C++ Source or Header  |  1997-07-22  |  10KB  |  459 lines

  1.  
  2. static char rcsid[] =
  3.     "$Id: pvmwinrexec.c,v 1.2 1997/07/02 17:53:10 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         PVM version 3.4:  Parallel Virtual Machine System
  7.  *               University of Tennessee, Knoxville TN.
  8.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  9.  *                   Emory University, Atlanta GA.
  10.  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
  11.  *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
  12.  *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
  13.  *                   (C) 1997 All Rights Reserved
  14.  *
  15.  *                              NOTICE
  16.  *
  17.  * Permission to use, copy, modify, and distribute this software and
  18.  * its documentation for any purpose and without fee is hereby granted
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both the copyright notice and this permission notice appear in
  21.  * supporting documentation.
  22.  *
  23.  * Neither the Institutions (Emory University, Oak Ridge National
  24.  * Laboratory, and University of Tennessee) nor the Authors make any
  25.  * representations about the suitability of this software for any
  26.  * purpose.  This software is provided ``as is'' without express or
  27.  * implied warranty.
  28.  *
  29.  * PVM version 3 was funded in part by the U.S. Department of Energy,
  30.  * the National Science Foundation and the State of Tennessee.
  31.  */
  32.  
  33.  
  34. #include <process.h>
  35.  
  36. #pragma warning(disable: 4699)
  37.  
  38. #define STRICT
  39. #pragma warning(disable: 4201)
  40. #include <windows.h>
  41. #pragma warning(default: 4201)
  42. #include <winsock.h>
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46.  
  47. #include <signal.h>
  48.  
  49. static void PassOutputThread(void);
  50. static void PassErrorThread(void);
  51.  
  52. HANDLE hStdIn, hStdOut, hStdErr;
  53.  
  54. static char *GetPassword(void);
  55. int MyOpenService(const char *remote_host);
  56. static void Cleanup(void);
  57. static HANDLE PassOutput(void);
  58. static HANDLE PassError(void);
  59.  
  60. static BOOL SendZString(const char *);
  61. static BOOL GetErrString(char *, size_t);
  62. extern void Wait(HANDLE, DWORD *);
  63.  
  64. static SOCKET sIO = INVALID_SOCKET;
  65. static SOCKET sErr = INVALID_SOCKET;
  66. char *res;
  67.  
  68. char *hn;
  69. int found_mess=0;
  70. int errno;
  71.  
  72. int rexec(char *hostname, char *username, char *command,char *retresult)
  73. {
  74.     char *password;
  75.     size_t cmdlen;
  76.     int i;
  77.     HANDLE idIn = 0;
  78.     HANDLE idOut, idErr;
  79.     DWORD rvIn, rvOut, rvErr;
  80.  
  81.     res=malloc(512*sizeof(char));
  82.  
  83.     hn=hostname;
  84.  
  85.     hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  86.     hStdErr = GetStdHandle(STD_ERROR_HANDLE);
  87.  
  88.     password = NULL;
  89.     
  90.     if (!username) {
  91.         username = MyGetUserName();
  92.     }
  93.  
  94.     if (!password) {
  95.         password = GetPassword();
  96.     }
  97.  
  98.     if (!MyOpenService(hostname))
  99.         return 0;
  100.  
  101.     SendZString(username);
  102.     SendZString(password);
  103.     memset (password, '\0', strlen(password));
  104.     SendZString(command);
  105.  
  106.     if (!GetErrString(command, sizeof command)) {
  107.         fprintf(stderr, "Remote aborted connection without initiating protocol: %d.\n",
  108.             WSAGetLastError());
  109.         return 0;
  110.     }
  111.  
  112.     if (*command != '\0') {
  113.         char *p = command;
  114.         if (*p == '\001') {
  115.             p++;
  116.         }
  117.         fprintf(stderr, "Remote aborted connection: %s\n", p);
  118.         return 0;
  119.     }
  120.  
  121.     if (shutdown(sIO, 1) == SOCKET_ERROR) {
  122.         fprintf(stderr, "Failed to shutdown from input socket: error = %d.\n",
  123.             WSAGetLastError());
  124.         return 0;
  125.     }
  126.  
  127.     idOut = PassOutput();
  128.     idErr = PassError();
  129.  
  130.     Wait(idOut, &rvOut);
  131.     Wait(idErr, &rvErr);
  132.      
  133.     
  134.     strcpy(retresult,res);
  135.         
  136.     return (int)rvOut;
  137. }
  138.  
  139.  
  140. static char *GetPassword()
  141. {
  142.     static char password[30];
  143.     char *p;
  144.     HANDLE hConIn, hConOut;
  145.     DWORD dwMode;
  146.     DWORD cbRead, cbWritten;
  147.  
  148.     hConIn = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
  149.         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
  150.  
  151.     if (hConIn == INVALID_HANDLE_VALUE) {
  152.         fprintf(stderr, "Can't open Console for input: %lu\n", GetLastError());
  153.         exit(1);
  154.     }
  155.  
  156.     hConOut = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
  157.         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
  158.  
  159.     if (hConOut == INVALID_HANDLE_VALUE) {
  160.         fprintf(stderr, "Can't open Console for output: %lu\n", GetLastError());
  161.         exit(1);
  162.     }
  163.  
  164.     (void) WriteFile(hConOut, "Password: ", 10, &cbWritten, 0);
  165.  
  166.     if (!GetConsoleMode(hConIn, &dwMode)) {
  167.         fprintf(stderr, "Can't Console input mode: %lu\n", GetLastError());
  168.         exit(1);
  169.     }
  170.  
  171.     dwMode &= ~(ENABLE_ECHO_INPUT);
  172.  
  173.     (void) signal(SIGINT, SIG_IGN);
  174.  
  175.     (void)SetConsoleMode(hConIn, dwMode);
  176.  
  177.     (void)ReadFile(hConIn, password, sizeof password, &cbRead, 0);
  178.  
  179.     dwMode |= ENABLE_ECHO_INPUT;
  180.     (void)SetConsoleMode(hConIn, dwMode);
  181.  
  182.     (void) signal(SIGINT, SIG_DFL);
  183.     
  184.     (void) WriteFile(hConOut, "\r\n", 2, &cbWritten, 0);
  185.  
  186.  
  187.     (void) CloseHandle(hConIn);
  188.     (void) CloseHandle(hConOut);
  189.  
  190.     if ((p=strchr(password, '\r')) != NULL) {
  191.         *p = '\0';
  192.     }
  193.  
  194.     if ((p=strchr(password, '\n')) != NULL) {
  195.         *p = '\0';
  196.     }
  197.  
  198.     return password;
  199. }
  200.  
  201.  
  202. static HANDLE PassOutput()
  203. {
  204.     HANDLE id;
  205.  
  206.     id = (HANDLE) _beginthread(PassOutputThread, 0, NULL);
  207.     if ((long)id == -1) {
  208.         fprintf(stderr, "Could not start output passing thread: error = %lu\n", GetLastError());
  209.         exit(1);
  210.     }
  211.     return id;
  212. }
  213.  
  214. extern int debugmask;
  215. static void PassOutputThread(void)
  216. {
  217.  
  218.  
  219.     DWORD retval = 1;
  220.     int count=0;
  221.     char *buf;
  222.     int noresult;
  223.     int i=0;
  224.  
  225.     buf = malloc(512*sizeof (char));
  226.  
  227.     while ((count=recv(sIO, &buf[i], sizeof buf, 0)) > 0) {
  228.     
  229.         i+=count;
  230.     }
  231.     buf[i]=0;
  232.  
  233.     if (noresult = (strncmp(buf, "ddpro", 5) == 0)) {
  234.         sprintf(res,"stdout@%s: %s\n",hn,buf);
  235.         retval=0;
  236.     }
  237.     if (!noresult)
  238.         retval =1;
  239.     
  240.  
  241.     if (count == -1) {
  242.         fprintf(stderr, "Error passing standard output from socket: error = %d.\n",
  243.             WSAGetLastError());
  244.         retval = 1;
  245.     }
  246.  
  247.     if (count != -1) {
  248.         if (shutdown(sIO, 0) == SOCKET_ERROR) {
  249.             fprintf(stderr, "Failed to shutdown standard output socket: error = %d.\n",
  250.                 WSAGetLastError());
  251.             retval = 1;
  252.         }
  253.     }
  254.     
  255.     free(buf);
  256. final:
  257.     ExitThread(retval);
  258.  
  259. }
  260.  
  261.  
  262. static HANDLE PassError()
  263. {
  264.     HANDLE id;
  265.  
  266.     id = (HANDLE) _beginthread(PassErrorThread, 0, NULL);
  267.     if ((long)id == -1) {
  268.         fprintf(stderr, "Could not start error passing thread: error = %lu\n", GetLastError());
  269.         exit(1);
  270.     }
  271.     return id;
  272. }
  273.  
  274. static void PassErrorThread(void)
  275. {
  276.     
  277.     DWORD retval = 0;
  278.     int count=0;
  279.     char *buf;
  280.  
  281.     buf=malloc(4096*sizeof(char));
  282.  
  283.     while ((count=recv(sErr, buf, sizeof buf, 0)) > 0) {
  284.         if (!win32_write_file(hStdErr, buf, count)) {
  285.             fprintf(stderr, "Error writing to standard error: error = %lu.\n", GetLastError());
  286.             retval = 1;
  287.             break;
  288.         }
  289.     }
  290.  
  291.     if (count == -1) {
  292.         fprintf(stderr, "Error passing standard error from socket: error = %d.\n",
  293.             WSAGetLastError());
  294.         retval = 1;
  295.     }
  296.  
  297.     if (count != -1) {
  298.         if (shutdown(sErr, 0) == SOCKET_ERROR) {
  299.             fprintf(stderr, "Failed to shutdown standard error socket: error = %d.\n",
  300.                 WSAGetLastError());
  301.             retval = 1;
  302.         }
  303.     }
  304.  
  305.  
  306.     ExitThread(retval);
  307.  
  308. }
  309.  
  310.  
  311. int MyOpenService(const char *remote_host)
  312. {
  313.     WSADATA wsadata;
  314.  
  315.     struct sockaddr_in server_addr, my_err_addr, junk_addr;
  316.     struct servent *sv;
  317.     struct hostent *hent;
  318.     static char portbuf[30];
  319.     SOCKET sTmp;
  320.     int addr_len;
  321.  
  322.     if (WSAStartup(MAKEWORD(1,1), &wsadata) != 0) {
  323.         fprintf(stderr, "Failed to initialize TCP/IP: error=%d.\n", WSAGetLastError());
  324.         return(0);
  325.     }
  326.  
  327.     if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) {
  328.         fprintf(stderr, "Old version of TCP/IP: error=%d.\n", WSAGetLastError());
  329.         return (0);
  330.     }
  331.     if (atexit(Cleanup) != 0) {    
  332.  
  333.         WSACleanup();
  334.         fprintf(stderr, "Could not register TCP/IP cleanup function.\n");
  335.         return(0);
  336.     }
  337.  
  338.     hent = gethostbyname(remote_host);
  339.     if(!hent) {
  340.         fprintf(stderr, "Lookup of server hostname failed: error=%d.\n",
  341.             WSAGetLastError());
  342.         return (0);
  343.     }
  344.  
  345.     sv=getservbyname("exec", "tcp");
  346.     if (!sv) {
  347.         fprintf(stderr, "Lookup of port number for rexec service failed: error=%d.\n",
  348.             WSAGetLastError());
  349.         return(0);
  350.     }
  351.  
  352.     memcpy((char *)&server_addr.sin_addr, hent->h_addr, hent->h_length);
  353.     server_addr.sin_family = hent->h_addrtype;
  354.     server_addr.sin_port = sv->s_port;
  355.  
  356.     if((sIO=socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  357.         fprintf(stderr, "I/O socket creation failed: error=%d.\n",
  358.             WSAGetLastError());
  359.         return(0);
  360.     }
  361.  
  362.     if(connect(sIO, (struct sockaddr *)&server_addr, sizeof server_addr) == SOCKET_ERROR) {
  363.         fprintf(stderr, "I/O socket connection failed: error=%d.\n",
  364.             WSAGetLastError());
  365.         return(0);
  366.     }
  367.  
  368.     memset(&my_err_addr, '\0', sizeof my_err_addr);
  369.     my_err_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  370.     my_err_addr.sin_family = AF_INET;
  371.     my_err_addr.sin_port = 0;
  372.  
  373.     if ((sTmp=socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  374.         fprintf(stderr, "Error socket creation failed: error=%d.\n",
  375.             WSAGetLastError());
  376.         return(0);
  377.     }
  378.  
  379.     if (bind(sTmp, (struct sockaddr *)&my_err_addr, sizeof my_err_addr) == SOCKET_ERROR) {
  380.         fprintf(stderr, "Error socket bind failed: error=%d.\n",
  381.             WSAGetLastError());
  382.         (void) closesocket(sTmp);
  383.         return(0);
  384.     }
  385.  
  386.     if (listen(sTmp, 1) == SOCKET_ERROR) {
  387.         fprintf(stderr, "Error socket listen failed: error=%d.\n",
  388.             WSAGetLastError());
  389.         (void) closesocket(sTmp);
  390.         return(0);
  391.     }    
  392.  
  393.     addr_len = sizeof my_err_addr;
  394.     if (getsockname(sTmp, (struct sockaddr *)&my_err_addr, &addr_len) == SOCKET_ERROR) {
  395.         fprintf(stderr, "Error socket bind failed: error=%d.\n",
  396.             WSAGetLastError());
  397.         (void) closesocket(sTmp);
  398.         return(0);
  399.     }
  400.  
  401.     sprintf(portbuf, "%hu", ntohs(my_err_addr.sin_port));
  402.  
  403.     SendZString(portbuf);
  404.  
  405.     addr_len = sizeof junk_addr;
  406.     if ((sErr = accept(sTmp, (struct sockaddr *)&junk_addr, &addr_len))
  407.         == INVALID_SOCKET) {
  408.         fprintf(stderr, "Error socket accept failed: error=%d.\n",
  409.             WSAGetLastError());
  410.         (void) closesocket(sTmp);
  411.         return(0);
  412.     }
  413.  
  414.     (void) closesocket(sTmp);
  415.     return 1;
  416. }
  417.  
  418. static void Cleanup(void)
  419. {
  420.     if (sIO != INVALID_SOCKET) {
  421.         (void)closesocket(sIO);
  422.     }
  423.  
  424.     if (sErr != INVALID_SOCKET) {
  425.         (void)closesocket(sErr);
  426.     }
  427.  
  428.  
  429.     WSACleanup();
  430. }
  431.  
  432.  
  433. static BOOL SendZString(const char *str)
  434. {
  435.     return win32_write_socket(sIO, str, strlen(str)+1);
  436. }
  437.  
  438.  
  439. static BOOL GetErrString(char *str, size_t len)
  440. {
  441.     size_t pos = 0;
  442.  
  443.     while (pos < len) {
  444.         char ch;
  445.         if (recv(sIO, &ch, 1, 0) != 1) {
  446.             return FALSE;
  447.         }
  448.         str[pos++] = ch;
  449.         if (ch == '\0') {
  450.             return TRUE;
  451.         }
  452.         if (ch == '\n') {
  453.             return TRUE;
  454.         }
  455.     }
  456.     return FALSE;
  457. }
  458.  
  459.